/* api */
import { getAsyncSystemFrameInitData } from '@src/api/InitDataApi'
import { getPcHomePageMenuList } from '@src/api/UserCenterApi'
/* components */
import { RoleViewForm, RoleViewAuthView } from '@src/modules/account/roleService/component'
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
/* hooks */
import { useRoleViewRoleAuthUpdate } from "@src/modules/account/roleService/hooks"
import { useStoreCurrentSelectRole, useStoreFetchAuthGroups, useStoreFetchRoleTree, useStoreInitData, useStoreMode, useStoreRoles } from "@src/modules/account/roleService/store/hooks"
import useLoading from '@src/modules/account/roleService/hooks/useLoading'
import { useStoreRoleCurrentProduct } from '@src/modules/account/roleService/store/hooks'
/* scss */
import '@src/modules/account/roleService/component/RoleViewContentEditView/index.scss'
/* model */
import Role from '@model/entity/Role/Role'
import { RoleViewFormVM } from '@src/modules/account/roleService/component/RoleViewForm'
import { RoleViewAuthViewVM } from '@src/modules/account/roleService/component/RoleViewAuthView'
import { SAVE_SUCCESS } from '@src/model/const/Alert'
import MsgModel from '@model/MsgModel'
import Auth from '@model/entity/Auth'
import { SHBProductLineEnum } from '@shb-lib/tenant'
/* vue */
import { ComponentInstance, computed, ComputedRef, defineComponent, nextTick, Ref, ref } from 'vue'
import { RoleViewInitDataType } from '@src/modules/account/roleService/types'
/* util */
import { transformToRoleAuthSaveModel } from '@src/modules/account/roleService/component/RoleViewContentEditView/util'
import Log from '@src/util/log'
import { message } from '@src/util/message'
import { loadingPromise } from '@src/modules/account/roleService/util'
import { getRootWindow } from '@src/util/dom'
import { findComponentDownward } from '@src/util/assist'
import { isEmpty } from '@src/util/type'

export type RoleViewContentEditViewProps = {

}

export interface RoleViewContentEditViewSetupState {
  currentSelectRole: ComputedRef<Role>;
}

export enum RoleViewContentEditViewEventEnum {
  Input = 'input'
}

export type RoleViewContentEditViewEmitsOptions = {
  input: () => void;
}

export type RoleViewContentEditViewInstance = ComponentInstance & RoleViewContentEditViewSetupState
export type RoleViewContentEditViewVM = RoleViewContentEditViewSetupState & RoleViewContentEditViewProps & ComponentInstance

export default defineComponent({
  name: ComponentNameEnum.RoleViewContentEditView,
  emits: [
    RoleViewContentEditViewEventEnum.Input
  ],
  setup(props: RoleViewContentEditViewProps, { slots, emit }) {
    
    const { currentSelectRole, currentRoleId } = useStoreCurrentSelectRole()
    const { roles } = useStoreRoles()
    const { initData: storeInitData, setInitData } = useStoreInitData()
    const { currentProduct } = useStoreRoleCurrentProduct()
    
    const { setUserViewMode } = useStoreMode()
    
    const fetchAuthGroups = useStoreFetchAuthGroups()
    const roleAuthUpdate = useRoleViewRoleAuthUpdate()
    const fetchRoleTree = useStoreFetchRoleTree(true)
    
    const { loading, setLoading } = useLoading()
    
    const RoleViewFormComponent: Ref<RoleViewFormVM | null> = ref(null)
    const RoleViewAuthViewComponent: Ref<RoleViewAuthViewVM | null> = ref(null)
    
    const referenceRoles = computed(() => {
      return roles.value
    })
    
    const referenceRoleId: Ref<string> = ref('')
    
    function onReferenceRoleIdChangeHandler(value: string): void {
      referenceRoleId.value = value
      fetchAuthGroups(value)
    }
    
    function onCopyRoleClickHandler() {
      
      if (isEmpty(referenceRoleId.value)) {
        return
      }
      
      fetchAuthGroups(referenceRoleId.value)
    }
    
    function onClickCancelEditRoleHandler() {
      setUserViewMode()
    }
    
    function onClickConfirmEditRoleHandler() {
      setUserViewMode()
    }
    
    return {
      currentSelectRole,
      referenceRoleId,
      referenceRoles,
      loading,
      currentRoleId,
      storeInitData,
      currentProduct,
      roleAuthUpdate,
      fetchRoleTree,
      setLoading,
      onReferenceRoleIdChangeHandler,
      onClickCancelEditRoleHandler,
      onClickConfirmEditRoleHandler,
      fetchAuthGroups,
      setInitData,
      onCopyRoleClickHandler,
      RoleViewFormComponent,
      RoleViewAuthViewComponent
    }
    
  },
  methods: {
    getRoleViewFormComponent(): RoleViewFormVM {
      // @ts-ignore
      return (this.RoleViewFormComponent || this.$refs.RoleViewFormComponent || {}) as RoleViewFormVM
    },
    getRoleViewAuthViewComponent(): RoleViewAuthViewVM {
      return (this.RoleViewAuthViewComponent || this.$refs.RoleViewAuthViewComponent || {}) as RoleViewAuthViewVM
    },
    async getChildComponentData() {
      
      const roleViewFormComponent = this.getRoleViewFormComponent()
      const roleViewAuthViewComponent = this.getRoleViewAuthViewComponent()
      
      const form = roleViewFormComponent?.outsideGetForm() || {}
      const checkedKeys = await roleViewAuthViewComponent?.outsideGetCheckedKeys() || []
      const authTreeData = roleViewAuthViewComponent?.outsideGetAuthTreeData() || []
      
      return {
        form,
        checkedKeys,
        authTreeData,
      }
      
    },
    async onClickConfirmButtonHandler() {
      
      await loadingPromise(this.loading)
      
      const roleViewFormComponent = this.getRoleViewFormComponent()
      const isValid = await roleViewFormComponent?.validate()
      
      if (!isValid) {
        Log.error(isValid, this.onClickConfirmButtonHandler.name)
        return
      }
      
      this.setLoading()
      
      const { form, authTreeData } = await this.getChildComponentData()
      const roleId = this.currentRoleId
      const productLine = this.currentProduct as SHBProductLineEnum
      
      const params = transformToRoleAuthSaveModel(form, authTreeData, roleId, productLine)
      
      if(!params.authorityBOList.length) {
        message.error(this.$t('common.placeholder.allotPermission') as string)
        this.setLoading(false)
        return
      } 
      
      this.roleAuthUpdate(params).then(result => {
        
        const isFail = MsgModel.isFail(result)
        
        if (isFail) {
          message.error(result.message)
          return
        }
        
        message.success(SAVE_SUCCESS)
        
        this.onClickConfirmEditRoleHandler()
        
        this.fetchAuthGroups()
        
        this.fetchRoleTree(params.name)
        
        this.fetchInitData()
        
        
      })
      
    },
    fetchInitData() {
      getAsyncSystemFrameInitData().then(async result => {
          
        const initData = result?.data?.initJson || {}
        const isFail = MsgModel.isFail(result)
        
        if (isFail) return
        
        try {
          // 获取左侧菜单
          const { data } = await getPcHomePageMenuList();
          
          initData.barPageList = data.barPageList || [];
          initData.morePageList = data.morePageList || [];
          initData.showUploadTenantLogo = data.showUploadTenantLogo;
          initData.calendar = data.showCalendar;
          initData.notice = data.showNotice;
          
        } catch(error) {
          Log.error(error, getAsyncSystemFrameInitData.name)
        }
        
        try {
          
          const auth: Auth = initData?.user?.auth || {}
          const newInitData: RoleViewInitDataType = {
            ...this.storeInitData,
            authorities: auth,
          }
          
          this.setInitData(newInitData)
          
        } catch (error) {
          Log.error(error, getAsyncSystemFrameInitData.name)
        }
        
        
        try {
          
          const rootWindow = getRootWindow(window)
          const barPageList = initData.barPageList || []
          const morePageList = initData.morePageList || []
          
          const globalInstance = rootWindow.getGlobalRootInstance()
          const elMenuComponent = findComponentDownward(globalInstance, 'ElMenu')
          const openedMenus = elMenuComponent?.openedMenus || []
          const activeIndex = elMenuComponent?.activeIndex || ''
          
          rootWindow.reBuildMenus(barPageList, morePageList)
          
          rootWindow._init = JSON.stringify(initData)
          
          nextTick(() => {
            elMenuComponent.openedMenus = openedMenus
            elMenuComponent.activeIndex = activeIndex
          })
          
          setTimeout(() => {
            elMenuComponent.openedMenus = openedMenus
            elMenuComponent.activeIndex = activeIndex
          }, 3000)
          
          
        } catch (error) {
          Log.error(error, getAsyncSystemFrameInitData.name)
        }
        
      })
    }
  },
  render() {
    return (
      <div class={ComponentNameEnum.RoleViewContentEditView}>
        
        <div class="role-view-content-edit-view__content">
          
          <RoleViewForm ref="RoleViewFormComponent" />
          
          <div class="role-view-content-edit-view__ref-block">
            
            <span class="role-view-content-edit-view__ref-block-name">
              {this.$t('common.base.exampleRole')}
            </span>
            
            <el-select value={this.referenceRoleId} placeholder={this.$t('common.base.pleaseSelect')} onChange={this.onReferenceRoleIdChangeHandler}>
              {
                this.referenceRoles.map(role => {
                  return (
                    <el-option
                      key={role.id}
                      label={role.name || ''}
                      value={role.id}
                    />
                  )
                })
              }
            </el-select>
            
            <el-tooltip content={this.$t('account.defaultCopyPermisson')} placement="top">
              <i class="iconfont icon-jieshishuoming1"></i>
            </el-tooltip>
            
          </div>
          
          <div class="role-view-content-edit-view-auth-tree">
            <RoleViewAuthView ref="RoleViewAuthViewComponent" />
          </div>
          
        </div>
        
        <div class="role-view-content-edit-view__footer">
          <el-button type="primary" onClick={this.onClickConfirmButtonHandler}>
            {this.$t('common.base.save')}
          </el-button>
          <el-button type="ghost" onClick={this.onClickCancelEditRoleHandler}>
            {this.$t('common.base.cancel')}
          </el-button>
        </div>
        
      </div>
    ) as any
  }
}) as any
